package com.yxplearn.mybatisplus.mybatis_sample;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInterceptor;
import com.yxplearn.mybatisplus.mybatis_sample.mapper.BlogMapper;
import com.yxplearn.mybatisplus.mybatis_sample.pojo.Blog;
import com.yxplearn.mybatisplus.util.RandomUtils;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.logging.log4j.core.config.Configurator;
import org.junit.Before;
import org.junit.Test;

import javax.sql.DataSource;
import java.util.*;

public class Application {

    private static BlogMapper blogMapper;

//    public static void main(String[] args) {
//        DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
//        TransactionFactory transactionFactory = new JdbcTransactionFactory();
//        Environment environment = new Environment("development", transactionFactory, dataSource);
//        Configuration configuration = new Configuration(environment);
//        configuration.addInterceptor(new SimpleInterceptor("拦截器1"));
//        configuration.addMapper(BlogMapper.class);
//        sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
//        Blog blog = mapper.selectBlog(1);
//        System.out.println(blog);
//    }

    @Before
    public void initMyBatisConfig() {
        System.setProperty("appName", "mybatis-test");
        System.setProperty("logInfo", "xxpp");
        Configurator.initialize("log4j2", "log4j2-sit.xml");
        DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource);
        Configuration configuration = new Configuration(environment);
        // mapUnderscoreToCamelCase
//        lazyLoadingEnabled：延迟加载的全局开关。当开启时，所有关联对象都会延迟加载
//        aggressiveLazyLoading：当开启时，任何方法的调用都会加载该对象的所有属性。 否则，每个属性会按需加载
        // 注册别名  com.yxplearn.mybatisplus.mybatis_sample.mapper.BlogMapper
//        configuration.getTypeAliasRegistry().registerAliases("com.yxplearn.mybatisplus.mybatis_sample.pojo");
        configuration.addInterceptor(new SimpleInterceptor("拦截器1"));
        configuration.addInterceptor(new SimpleInterceptor2("拦截器2"));
        configuration.addInterceptor(new CampHumpInterceptor("字符串值转大写"));
//        configuration.addInterceptor(new PageInterceptor());
        configuration.addMapper(BlogMapper.class);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        blogMapper = sqlSession.getMapper(BlogMapper.class);
    }

    /**
     * 查询单个
     */
    @Test
    public void selectOne() {
        System.out.println(blogMapper.selectBlog(4));
    }

    /**
     * 查询一个集合
     */
    @Test
    public void selectBlogList() {
        blogMapper.selectBlogList().forEach(e -> {
            System.out.println(e.toString());
        });
    }

    /**
     * 统计总个数
     */
    @Test
    public void selectCount() {
        System.out.println(blogMapper.selectCount());
    }

    /**
     * 查询一条数据为map集合
     */
    @Test
    public void selectOneAsMapResult() {
        System.out.println(blogMapper.selectOneAsMapResult(8));
    }

    /**
     * 查询一条数据为map集合
     * [{name=xxppasss, id=4, age=1}, {name=sfasdf, id=5}, ..]
     */
    @Test
    public void selectListAsMapResult() {
        System.out.println(blogMapper.selectListAsMapResult());
    }

    /**
     * 查询多条数据为map集合
     * {4={name=xxppasss, id=4, age=1}, 5={name=sfasdf, id=5}, ..}
     */
    @Test
    public void selectListAsMapResult2() {
        System.out.println(blogMapper.selectListAsMapResult2());
    }

    /**
     * 模糊查询
     */
    @Test
    public void selectListLikeName() {
        System.out.println(blogMapper.selectListLikeName("xx"));
    }

    /**
     * 批量查询
     */
    @Test
    public void selectBlogListByIds() {
        System.out.println(blogMapper.selectBlogListByIds("4,8"));
    }

    /**
     * 自定义映射resultMap，也可以多对一处理映射
     * association  可以处理 pojo 中的自定义实体
     * collection 查询 list<pojo> 属性
     */
    @Test
    public void selectOneBlogAlgFromBlog() {
        System.out.println(blogMapper.selectOneBlogAlgFromBlog(8));
    }

    /**
     * where if
     * choose when otherwise  相当于 if else
     */
    @Test
    public void selectBlogByCondition() {
        blogMapper.selectBlogByCondition(8, null, 0);
//        Preparing: select * from blog where 1=1 and id = ? and name = ?
        blogMapper.selectBlogByCondition(8, "xp", 0);
    }

    /**
     * foreach 拼接 id in ( ? , ? , ? )
     */
    @Test
    public void selectBlogByArray() {
        blogMapper.selectBlogByArray(Arrays.asList(4, 6, 8));
    }

    /**
     * 查询单个 带缓存
     */
    @Test
    public void selectOneCache() {
        // 两次查询一样的语句一样的参数，将会默认使用到缓存
        System.out.println(blogMapper.selectOneCache(4));
        System.out.println(blogMapper.selectOneCache(4));
        blogMapper.updateOneById(4, "ffsg");
        System.out.println(blogMapper.selectOneCache(4));
    }

    /**
     * 参数识别方式
     * 实体类类型的参数
     * 使用@Param标识参数，单个参数可以不用 @Param
     */

    /**
     * 实体类型参数
     */
    @Test
    public void insertOne() {
        Blog xxpp = new Blog("xxpp");
        System.out.println(blogMapper.insertBlog(xxpp));
        System.out.println(xxpp.getId());
    }

    /**
     * 实体类型参数，添加功能获取自增的主键
     * useGeneratedKeys 设置使用自增的主键
     * keyProperty：因为增删改有统一的返回值是受影响的行数，因此只能将获取的自增的主键放在传输的参数user对象的某个属性中
     */
    @Test
    public void insertOneAndKey() {
        Blog xxpp = new Blog("xxpp");
        System.out.println(blogMapper.insertOneAndKey(xxpp));
        System.out.println(xxpp.getId());
    }

    /**
     * 批量插入
     */
    @Test
    public void insertList() {
        List<Blog> blogList = new ArrayList<>();
        for (int i = 1; i < 100; i++) {
            blogList.add(new Blog(RandomUtils.getStringWithCharacter(9)));
        }
        System.out.println(blogMapper.insertList(blogList));
    }

    /**
     * 多参数识别，@Param标识参数
     */
    @Test
    public void updateOneById() {
        blogMapper.updateOneById(4, "xxppasss");
    }

    /**
     * map类型的参数
     */
    @Test
    public void updateOneByIdMap() {
        Map<String, Object> paramMaps = new HashMap<>();
        paramMaps.put("id", 5);
        paramMaps.put("name", "sfasdf");
        blogMapper.updateOneByIdMap(paramMaps);
    }

    @Test
    public void selectBlogPage() {
        Page<Object> pageObject = PageHelper.startPage(1, 5);
        int pageSize = pageObject.getPageSize();
        for (int i = 1; i <= pageSize; i++) {
            PageHelper.startPage(i, 5);
            List<Blog> xxx = blogMapper.selectListLikeName("x");
            xxx.forEach(System.out::println);
            System.out.println("---- 第" + i + "页 ----" +
                    " pages:" + pageObject.getPages() +
                    " pageNum:" + pageObject.getPageNum() +
                    " pageSize:" + pageObject.getPageSize());
        }
    }

    @Test
    public void selectBlogPageSample() {
        Page<Object> pageObject = PageHelper.startPage(1, 5);
        List<Blog> xxx = blogMapper.selectListLikeName("x");
        xxx.forEach(System.out::println);
    }
}
